<template>
  <div class="telemetry-chart-container">
    <!-- 全局头部控制区 -->
    <div class="chart-header">
      <h3>遥测数据实时监控</h3> 
      <span style="text-align: center;">当前采集任务：{{ taskName }}</span>      
    </div>

    <!-- 多图表容器：根据窗口布局动态调整 -->
    <div
        class="multi-chart-wrapper scroll-wrapper"
        :style="chartGridStyle"
    >
      <!-- 无数据时显示提示 -->
      <div class="no-data-tip" v-if="validDataGroups.length === 0">
        正在等待接收UDP数据...
      </div>

      <!-- 循环渲染每个参数对应的独立图表 -->
      <div class="single-chart-item" v-for="(group, groupIndex) in validDataGroups" :key="group.paramId || groupIndex">
        <!-- 单图表头部：标题 + 单独操作 -->
        <div class="single-chart-header">
          <span class="chart-title">{{ group.paramName || `参数${groupIndex + 1}` }}</span>
        </div>

        <!-- 单图表主体（ECharts 实例） -->
        <v-chart
            class="single-chart"
            :option="getSingleChartOption(group, groupIndex)"
            :autoresize="true"
        />

        <!-- 单图表数据统计 -->
        <div class="single-chart-info">
          <div class="info-item">
            <span class="label">数据点:</span>
            <span class="value">{{ getOriginalDataPointsCount(group) }}</span>
          </div>
          <!-- 图表右下角时间显示 -->
          <div class="info-item">
            <span class="label">最新值:</span>
            <span class="value">{{ getLatestValue(group.y) }}</span>
          </div>
          <div class="info-item">
            <span class="label">时间:</span>
            <span class="value">{{ formatTimeForChart(group.x[group.x.length - 1]) }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import { TitleComponent, TooltipComponent, GridComponent } from 'echarts/components'
import VChart from 'vue-echarts'

// 注册ECharts必要组件
use([
  CanvasRenderer,
  LineChart,
  TitleComponent,
  TooltipComponent,
  GridComponent
])

/**
 * 组件属性定义
 * @property {Boolean} isCollecting - 控制是否自动启动实时更新
 * @property {Array} historicalData - 历史数据，格式: [{paramId: '', paramName: '', x:[], y:[]}, ...]
 * @property {Number} windowLayout - 窗口布局，控制每行图表数量
 * @property {Number} maxDataPoints - 每组数据最大保留点数
 */
const props = defineProps({
  isCollecting: {
    type: Boolean,
    default: false,
    description: '父组件控制是否启动数据采集'
  },
  historicalData: {
    type: Array,
    default: () => [],
    validator: (value) => {
      return value.every(item => 
        Array.isArray(item.x) && 
        Array.isArray(item.y) &&
        typeof item.paramId === 'string' &&
        typeof item.paramName === 'string'
      )
    },
    description: '历史数据，包含参数ID、名称和数据点'
  },
  windowLayout: {
    type: Number,
    default: 4,
    validator: (val) => [2, 3, 4].includes(val),
    description: '窗口布局，控制每行图表数量'
  },
  maxDataPoints: {
    type: Number,
    default: 100,
    description: '每组数据最大保留点数'
  },
  taskName: {
    type: String,
    default: '任务名称',
    description: '当前采集任务的名称'
  }
})

// 状态管理
const isRealTime = ref(false) // 全局实时更新开关
const dataGroups = ref([]) // 存储限制后的数据点，用于图表显示
const dataPointsCounters = ref({}) // 存储每个参数的数据点总数，key为paramId或paramName
let realTimeTimer = null // 实时更新定时器
const latestUpdateTime = ref('') // 全局最新更新时间

// -------------------------- 数据处理核心方法 --------------------------

/**
 * 过滤有效数据组(x/y数组长度一致的组)
 * @returns {Array} 有效数据组列表
 */
const validDataGroups = computed(() => {
  return dataGroups.value.filter(group => {
    return group.x.length === group.y.length
  })
})

/**
 * 获取原始数据的总点数
 * @param {Object} group - 当前显示的图表数据组
 * @returns {number} 原始数据的总点数
 */
const getOriginalDataPointsCount = (group) => {
  // 使用paramId或paramName作为key获取计数
  const key = group.paramId || group.paramName;
  // 如果有计数器记录，返回计数器值，否则返回当前显示的点数
  const allPointCount=dataPointsCounters.value[key];
  console.log('参数：',key);
  console.log('总数据点为:',allPointCount);
  return allPointCount || group.x.length;
}

/**
 * 获取数组中最新的值
 * @param {Array} arr - 数据数组
 * @returns {string} 格式化后的最新值或提示文本
 */
const getLatestValue = (arr) => {
  return arr.length > 0 ? arr[arr.length - 1].toFixed(2) : '暂无'
}

/**
 * 为图表右下角格式化时间显示（只显示时分秒）
 * @param {number} timestamp - 时间戳（毫秒）
 * @returns {string} 格式化的时间字符串
 */
const formatTimeForChart = (timestamp) => {
  // 计算小时、分钟、秒
  const hours = Math.floor(timestamp / 3600000);
  const minutes = Math.floor((timestamp % 3600000) / 60000);
  const seconds = Math.floor((timestamp % 60000) / 1000);
  
  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}

// -------------------------- 图表配置核心方法 --------------------------

/**
 * 动态生成图表网格样式（与窗口布局同步）
 */
const chartGridStyle = computed(() => {
  return {
    display: "grid",
    gridTemplateColumns: `repeat(${props.windowLayout}, 1fr)`,
    gap: "16px",
    overflowY: "auto",
    paddingBottom: "8px"
  };
});

/**
 * 生成单个图表的ECharts配置项
 * @param {Object} group - 单组数据: {paramId: '', paramName: '', x: [...], y: [...]} 
 * @param {number} groupIndex - 图表组索引
 * @returns {Object} ECharts配置对象
 */
const getSingleChartOption = (group, groupIndex) => {
  // 生成X轴时间标签（只显示毫秒部分）
  const xAxisData = group.x.map(timestamp => {
    // 提取毫秒部分
    const ms = timestamp % 1000;
    // 计算秒数（包含毫秒）
    const totalSeconds = Math.floor(timestamp / 1000);
    const sec = totalSeconds % 60;
    const min = Math.floor(totalSeconds / 60) % 60;
    const hour = Math.floor(totalSeconds / 3600);
    
    // 对于大量数据，只显示部分标签，避免重叠
    const showFullLabel = group.x.indexOf(timestamp) % Math.ceil(group.x.length / 5) === 0;
    
    if (showFullLabel) {
      // 显示完整的时分秒+毫秒
      return `${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;
    } else {
      // 只显示毫秒
      return `${ms.toString().padStart(3, '0')}`;
    }
  })

  // 为不同图表分配差异化颜色
  const colorList = [
    '#409EFF', '#67C23A', '#E6A23C', '#F56C6C',
    '#909399', '#20e7b8', '#722ED1', '#13C2C2',
    '#12a2f8', '#67f81f', '#f6980b', '#f64949',
  ]
  const chartColor = colorList[groupIndex % colorList.length]

  return {
    // 图表内部标题
    title: {
      text: `${group.paramName} - 趋势图`,
      left: 'center',
      textStyle: {
        fontSize: 12,
        color: '#666'
      },
      top: 5
    },
    // 鼠标悬浮提示配置
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        shadowStyle: { opacity: 0.1 }
      },
      formatter: (params) => {
        const pointIndex = params[0].dataIndex
        
        // 格式化完整时间戳（包含毫秒）
        const timestamp = group.x[pointIndex];
        const hours = Math.floor(timestamp / 3600000);
        const minutes = Math.floor((timestamp % 3600000) / 60000);
        const seconds = Math.floor((timestamp % 60000) / 1000);
        const ms = timestamp % 1000;
        const fullTime = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;
        
        return `
          <div style="padding: 4px 8px; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
            <div>时间: ${fullTime}</div>
            <div style="color: ${chartColor};">${group.paramName}: ${group.y[pointIndex].toFixed(2)}</div>
          </div>
        `
      }
    },
    // 图表网格布局
    grid: {
      left: '8%',
      right: '8%',
      bottom: '20%',
      top: '15%',
      containLabel: true
    },
    // X轴配置
      xAxis: {
        type: 'category',
        data: xAxisData,
        axisLabel: {
          rotate: 0,
          fontSize: 9,
          interval: group.x.length > 20 ? Math.floor(group.x.length / 10) : 0,
          color: '#999'
        },
        axisLine: { lineStyle: { color: '#eee' } },
        splitLine: { show: false }
      },
      // Y轴配置
      yAxis: {
        type: 'value',
        axisLabel: {
          fontSize: 9,
          color: '#999',
          formatter: (value) => value.toFixed(1)
        },
        splitLine: { lineStyle: { color: '#f8f8f8' } },
        axisTick: { show: false },
        // 自动适配Y轴范围
        min: (value) => {
          // 如果有数据，设置合适的最小值
          if (value.min !== undefined) {
            return Math.floor(value.min - Math.max(1, Math.abs(value.min * 0.1)));
          }
          return 0;
        },
        max: (value) => {
          // 如果有数据，设置合适的最大值
          if (value.max !== undefined) {
            return Math.ceil(value.max + Math.max(1, Math.abs(value.max * 0.1)));
          }
          return 100;
        }
      },
      // 折线系列配置
      series: [
        {
          name: group.paramName,
          type: 'line',
          data: group.y,
          smooth: true,
          symbol: 'circle',
          symbolSize: 3,
          lineStyle: {
            width: 1.5,
            color: chartColor
          },
          areaStyle: {
            opacity: 0.2,
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [
                { offset: 0, color: `${chartColor}90` },
                { offset: 1, color: `${chartColor}10` }
              ]
            }
          },
          emphasis: {
            symbolSize: 6
          }
        }
      ],
    // 无数据时的提示配置
    noDataLoadingOption: {
      text: '暂无数据',
      textStyle: { fontSize: 12, color: '#999' },
      effect: 'bubble'
    }
  }
}

// -------------------------- 实时更新与生命周期 --------------------------

/**
 * 切换全局实时更新状态
 */
const toggleRealTime = () => {
  isRealTime.value = !isRealTime.value

  if (isRealTime.value) {
    // 不需要立即添加数据点，只接收实际UDP数据
    latestUpdateTime.value = new Date().toLocaleTimeString()
  } else {
    // 停止定时更新
    if (realTimeTimer) {
      clearInterval(realTimeTimer)
      realTimeTimer = null
    }
  }
}

/**
 * 监听父组件的isCollecting状态
 */
watch(() => props.isCollecting, (newVal) => {
  if (newVal && !isRealTime.value) {
    toggleRealTime()
  } else if (!newVal && isRealTime.value) {
    toggleRealTime()
  }
}, { immediate: true })

/**
 * 监听历史数据变化，实时更新图表
 */
watch(() => props.historicalData, (newData) => {
  if (newData && newData.length > 0) {
    // 更新每个参数的数据点计数器
    newData.forEach(group => {
      const key = group.paramId || group.paramName;
      // 累加新接收到的数据点数量，而不是直接使用当前长度
      if (!dataPointsCounters.value[key]) {
        dataPointsCounters.value[key] = 0;
      }
      dataPointsCounters.value[key] += group.x.length;
    });
    
    // 使用限制后的数据点用于图表显示
    dataGroups.value = newData.map(group => ({
      paramId: group.paramId,
      paramName: group.paramName,
      x: group.x.slice(-props.maxDataPoints), // 限制数据点数量
      y: group.y.slice(-props.maxDataPoints)
    }));
    latestUpdateTime.value = new Date().toLocaleTimeString();
  }
}, { deep: true, immediate: true })

/**
 * 监听窗口布局变化，触发重绘
 */
watch(() => props.windowLayout, () => {
  // 布局变化时强制刷新图表
  dataGroups.value = [...dataGroups.value];
})

/**
 * 组件挂载时初始化数据
 */
onMounted(() => {
  if (props.historicalData.length > 0) {
    // 加载历史数据（限制每组最大点数）
    dataGroups.value = props.historicalData.map(group => {
      const limitedX = group.x.slice(-props.maxDataPoints)
      const limitedY = group.y.slice(-props.maxDataPoints)
      return { x: limitedX, y: limitedY }
    })
    latestUpdateTime.value = new Date().toLocaleTimeString()
  }
  // 不再自动生成模拟数据，只等待实际UDP数据
})

/**
 * 组件卸载时清理定时器
 */
onUnmounted(() => {
  if (realTimeTimer) {
    clearInterval(realTimeTimer)
  }
})

</script>

<style scoped>
/* 容器整体样式 */
.telemetry-chart-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: 12px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #f0f0f0;
}

/* 头部控制区 */
.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f5f5f5;
  flex-shrink: 0;
}

.chart-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.chart-controls {
  display: flex;
  gap: 8px;
}

/* 多图表容器（响应式网格布局） */
.multi-chart-wrapper {
  flex: 1;
  overflow-y: auto;
  padding-bottom: 8px;
}

/* 无数据提示 */
.no-data-tip {
  grid-column: 1 / -1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
  color: #999;
  font-size: 14px;
  background: #fafafa;
  border-radius: 4px;
}

/* 单图表项样式 */
.single-chart-item {
  display: flex;
  flex-direction: column;
  background: #fafafa;
  border-radius: 6px;
  padding: 12px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
  transition: transform 0.2s, box-shadow 0.2s;
  min-width: 240px; /* 最小宽度限制，避免过窄 */
}

.single-chart-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 3px 6px rgba(0,0,0,0.08);
}

/* 单图表头部 */
.single-chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.chart-title {
  font-size: 14px;
  font-weight: 500;
  color: #555;
}

/* 单图表主体 */
.single-chart {
  flex: 1;
  min-height: 200px;
  width: 100%;
}

/* 单图表数据统计 */
.single-chart-info {
  display: flex;
  justify-content: space-between;
  padding-top: 8px;
  margin-top: 8px;
  border-top: 1px dashed #eee;
  font-size: 12px;
}

.info-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 60px;
}

.info-item .label {
  color: #999;
  font-size: 11px;
  margin-bottom: 2px;
}

.info-item .value {
  color: #333;
  font-weight: 500;
}

/* 图表右下角时间显示样式 */
.chart-time {
  margin-left: auto;
  color: #666;
  font-size: 12px;
  font-family: monospace;
  display: flex;
  align-items: center;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .multi-chart-wrapper {
    grid-template-columns: 1fr !important;
  }

  .single-chart {
    min-height: 180px;
  }
}
</style>
